home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
676-700
/
681
/
term
/
source.lha
/
GadgetSupport.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-15
|
16KB
|
763 lines
/*
** $Id: GadgetSupport.c,v 1.3 92/05/15 22:24:44 olsen Sta Locker: olsen $
** $Revision: 1.3 $
** $Date: 92/05/15 22:24:44 $
**
** GadTools object management support routines
**
** Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
/* Some includes for starters. */
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <utility/tagitem.h>
#include <exec/memory.h>
#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <stdarg.h>
/* External data. */
extern struct Library *GadToolsBase;
extern struct Gadget *ActiveGadget;
/* This structure will help us to remember the current state of
* a GadTools object.
*/
struct GadgetSupportInfo
{
struct GadgetSupportInfo *PointBack; /* Points back to itself. */
struct Gadget *Gadget; /* Points back to the host. */
WORD Kind; /* Item type (BUTTON_KIND, STRING_KIND, etc.) */
UBYTE Key; /* The key to press. */
BYTE ReadOnly; /* LISTVIEW_KIND only: is this a read-only object? */
LONG Current, /* Current state or counter. */
Min, /* Minimum value for `Current'. */
Max; /* Maximum value for `Current'. */
};
/* Local routines. */
struct Gadget * CreateGadget(ULONG Kind,struct Gadget *Previous,struct NewGadget *New,...);
VOID FreeGadgets(struct Gadget *GadgetList);
VOID GT_SetGadgetAttrs(struct Gadget *Gadget,struct Window *Window,struct Requester *Requester,...);
VOID GT_ReplyIMsg(struct IntuiMessage *Message);
VOID KeySelect(struct Gadget **GadgetList,WORD Last,UBYTE Key,struct Window *Window,struct Gadget **Gadget,ULONG *Class,LONG *Code);
/* The original gadtools.library routines. */
struct Gadget * OldCreateGadgetA(ULONG,struct Gadget *,struct NewGadget *,struct TagItem *);
VOID OldFreeGadget(struct Gadget *);
VOID OldGT_SetGadgetAttrsA(struct Gadget *,struct Window *,struct Requester *,struct TagItem *);
VOID OldGT_ReplyIMsg(struct IntuiMessage *);
/* Pragma calls: the easy way. */
#pragma libcall GadToolsBase OldCreateGadgetA 1E A98004
#pragma libcall GadToolsBase OldFreeGadgets 24 801
#pragma libcall GadToolsBase OldGT_SetGadgetAttrsA 2A BA9804
#pragma libcall GadToolsBase OldGT_ReplyIMsg 4E 901
/* CreateGadget():
*
* A frontend to the original routine.
*/
struct Gadget *
CreateGadget(ULONG Kind,struct Gadget *Previous,struct NewGadget *New,...)
{
va_list VarArgs;
struct TagItem *TagList;
struct GadgetSupportInfo *Info = NULL;
WORD i;
UBYTE Underscore = 0;
struct Gadget *Result;
va_start(VarArgs,New);
TagList = (struct TagItem *)VarArgs;
switch(Kind)
{
case STRING_KIND:
case INTEGER_KIND:
case BUTTON_KIND:
case CHECKBOX_KIND:
case CYCLE_KIND:
case LISTVIEW_KIND:
case MX_KIND:
case PALETTE_KIND:
case SCROLLER_KIND:
case SLIDER_KIND:
for(i = 0 ; TagList[i] . ti_Tag != TAG_DONE ; i++)
{
if(TagList[i] . ti_Tag == GT_Underscore)
{
Underscore = TagList[i] . ti_Data;
break;
}
}
if(Underscore)
{
if(New -> ng_GadgetText)
{
for(i = 0 ; i < strlen(New -> ng_GadgetText) ; i++)
{
if(New -> ng_GadgetText[i] == Underscore)
{
if(New -> ng_GadgetText[i + 1] > 32)
{
if(Info = (struct GadgetSupportInfo *)AllocMem(sizeof(struct GadgetSupportInfo),MEMF_ANY | MEMF_CLEAR))
{
Info -> PointBack = Info;
Info -> Kind = Kind;
Info -> Key = New -> ng_GadgetText[i + 1];
if(Info -> Kind == PALETTE_KIND)
{
Info -> Current = 1;
Info -> Max = 1;
}
if(Info -> Kind == LISTVIEW_KIND)
Info -> Current = ~0;
break;
}
}
}
}
}
}
break;
default:
break;
}
New -> ng_UserData = Info;
if(Info)
{
struct Node *Node;
struct List *List;
LONG Count;
STRPTR *Strings;
BYTE ShowSelected = FALSE;
for(i = 0 ; TagList[i] . ti_Tag != TAG_DONE ; i++)
{
switch(TagList[i] . ti_Tag)
{
case GTCB_Checked:
case GTCY_Active:
case GTLV_Selected:
case GTMX_Active:
case GTSC_Top:
case GTSL_Level:
case GTPA_Color:
Info -> Current = TagList[i] . ti_Data;
break;
case GTSL_Min:
Info -> Min = TagList[i] . ti_Data;
break;
case GTSC_Total:
case GTSL_Max:
Info -> Max = TagList[i] . ti_Data;
break;
case GTPA_Depth:
Info -> Max = (1 << ((LONG)TagList[i] . ti_Data)) - 1;
break;
case GTLV_ReadOnly:
if(!ShowSelected)
Info -> ReadOnly = TRUE;
break;
case GTLV_ShowSelected:
ShowSelected = TRUE;
Info -> ReadOnly = FALSE;
break;
case GTCY_Labels:
case GTMX_Labels:
Count = 0;
if(Strings = (STRPTR *)TagList[i] . ti_Data)
{
while(Strings[Count])
Count++;
}
if(Count)
Info -> Max = Count - 1;
break;
case GTLV_Labels:
Count = 0;
if(TagList[i] . ti_Data != NULL && TagList[i] . ti_Data != ~0)
{
List = (struct List *)TagList[i] . ti_Data;
Node = List -> lh_Head;
while(Node -> ln_Succ)
{
Count++;
Node = Node -> ln_Succ;
}
}
if(Count)
Info -> Max = Count - 1;
break;
default:
break;
}
}
if(Result = OldCreateGadgetA(Kind,Previous,New,TagList))
Info -> Gadget = Result;
else
FreeMem(Info,sizeof(struct GadgetSupportInfo));
}
else
Result = OldCreateGadgetA(Kind,Previous,New,TagList);
va_end(VarArgs);
return(Result);
}
/* GT_SetGadgetAttrs():
*
* A frontend to the original routine.
*/
VOID
GT_SetGadgetAttrs(struct Gadget *Gadget,struct Window *Window,struct Requester *Requester,...)
{
va_list VarArgs;
struct TagItem *TagList;
struct GadgetSupportInfo *Info;
va_start(VarArgs,Requester);
TagList = (struct TagItem *)VarArgs;
if(Info = (struct GadgetSupportInfo *)Gadget -> UserData)
{
if(Info -> PointBack == Info)
{
struct Node *Node;
struct List *List;
LONG Count;
STRPTR *Strings;
WORD i;
for(i = 0 ; TagList[i] . ti_Tag != TAG_DONE ; i++)
{
switch(TagList[i] . ti_Tag)
{
case GTCB_Checked:
case GTCY_Active:
case GTLV_Selected:
case GTMX_Active:
case GTSC_Top:
case GTSL_Level:
case GTPA_Color:
Info -> Current = TagList[i] . ti_Data;
break;
case GTSL_Min:
Info -> Min = TagList[i] . ti_Data;
break;
case GTSC_Total:
case GTSL_Max:
Info -> Max = TagList[i] . ti_Data;
break;
case GTCY_Labels:
Count = 0;
if(Strings = (STRPTR *)TagList[i] . ti_Data)
{
while(Strings[Count])
Count++;
}
if(Count)
Info -> Max = Count - 1;
break;
case GTLV_Labels:
Count = 0;
if(TagList[i] . ti_Data != NULL && TagList[i] . ti_Data != ~0)
{
List = (struct List *)TagList[i] . ti_Data;
Node = List -> lh_Head;
while(Node -> ln_Succ)
{
Count++;
Node = Node -> ln_Succ;
}
}
if(Count)
Info -> Max = Count - 1;
break;
default:
break;
}
}
}
}
OldGT_SetGadgetAttrsA(Gadget,Window,Requester,TagList);
va_end(VarArgs);
}
/* FreeGadgets(struct Gadget *GadgetList):
*
* A frontend to the original routine.
*/
VOID
FreeGadgets(struct Gadget *GadgetList)
{
struct Gadget *Gadget = GadgetList;
struct GadgetSupportInfo *Info;
while(Gadget)
{
if(Info = (struct GadgetSupportInfo *)Gadget -> UserData)
{
if(Info -> PointBack == Info && Info -> Gadget == Gadget)
FreeMem(Info,sizeof(struct GadgetSupportInfo));
}
Gadget = Gadget -> NextGadget;
}
OldFreeGadgets(GadgetList);
}
/* GT_ReplyIMsg(struct IntuiMessage *Message):
*
* A frontend to the original routine.
*/
VOID
GT_ReplyIMsg(struct IntuiMessage *Message)
{
if(Message)
{
if(Message -> Class == IDCMP_GADGETUP || Message -> Class == IDCMP_GADGETDOWN || Message -> Class == IDCMP_MOUSEMOVE)
{
struct Gadget *Gadget;
if(Gadget = (struct Gadget *)Message -> IAddress)
{
struct GadgetSupportInfo *Info = Gadget -> UserData;
if(Info)
{
if(Info -> PointBack == Info)
{
LONG Value = (WORD)Message -> Code;
switch(Info -> Kind)
{
case CHECKBOX_KIND:
if(Gadget -> Flags & GFLG_SELECTED)
Info -> Current = TRUE;
else
Info -> Current = FALSE;
break;
case CYCLE_KIND:
Info -> Current = Message -> Code;
break;
case LISTVIEW_KIND:
Info -> Current = Message -> Code;
break;
case MX_KIND:
Info -> Current = Message -> Code;
break;
case SCROLLER_KIND:
Info -> Current = Message -> Code;
break;
case SLIDER_KIND:
if(Info -> Min >= 0 && Value < 0)
Info -> Current = Message -> Code;
else
Info -> Current = Value;
break;
case PALETTE_KIND:
Info -> Current = Message -> Code;
break;
default:
break;
}
}
}
}
}
}
OldGT_ReplyIMsg(Message);
}
/* KeySelect():
*
* Handles gadget keystroke activation.
*/
VOID
KeySelect(struct Gadget **GadgetList,WORD Last,UBYTE Key,struct Window *Window,struct Gadget **Gadget,ULONG *Class,LONG *Code)
{
if(Key == '\033' && (Window -> Flags & WFLG_CLOSEGADGET))
*Class = IDCMP_CLOSEWINDOW;
else
{
struct GadgetSupportInfo *Info;
WORD i;
BYTE Forward,
GotIt = FALSE;
for(i = 0 ; !GotIt && i <= Last ; i++)
{
if(!(GadgetList[i] -> Flags & GFLG_DISABLED))
{
if(Info = GadgetList[i] -> UserData)
{
if(Info -> PointBack == Info)
{
if(ToUpper(Info -> Key) == ToUpper(Key))
{
if(ToUpper(Info -> Key) == Key)
Forward = FALSE;
else
Forward = TRUE;
switch(Info -> Kind)
{
case STRING_KIND:
case INTEGER_KIND: ActivateGadget(ActiveGadget = GadgetList[i],Window,NULL);
*Class = IDCMP_GADGETDOWN;
*Code = 0;
*Gadget = GadgetList[i];
GotIt = TRUE;
break;
case BUTTON_KIND: *Class = IDCMP_GADGETUP;
*Code = 0;
*Gadget = GadgetList[i];
GotIt = TRUE;
break;
case CHECKBOX_KIND: GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTCB_Checked, Info -> Current ? FALSE : TRUE,
TAG_DONE);
*Class = IDCMP_GADGETUP;
*Code = Info -> Current;
*Gadget = GadgetList[i];
GotIt = TRUE;
break;
case CYCLE_KIND: if(Forward)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTCY_Active, (Info -> Current == Info -> Max) ? 0 : Info -> Current + 1,
TAG_DONE);
}
else
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTCY_Active, Info -> Current ? Info -> Current - 1 : Info -> Max,
TAG_DONE);
}
*Class = IDCMP_GADGETUP;
*Code = Info -> Current;
*Gadget = GadgetList[i];
GotIt = TRUE;
break;
case LISTVIEW_KIND: if(Forward)
{
if(Info -> Current == ~0)
Info -> Current = -1;
if(Info -> Current < Info -> Max)
{
if(Info -> ReadOnly)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTLV_Top, Info -> Current + 1,
TAG_DONE);
}
else
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTLV_Selected, Info -> Current + 1,
GTLV_Top, Info -> Current + 1,
TAG_DONE);
}
*Class = IDCMP_GADGETUP;
*Code = Info -> Current;
*Gadget = GadgetList[i];
}
}
else
{
if(Info -> Current == ~0)
Info -> Current = Info -> Max + 1;
if(Info -> Current > Info -> Min)
{
if(Info -> ReadOnly)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTLV_Top, Info -> Current - 1,
TAG_DONE);
}
else
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTLV_Selected, Info -> Current - 1,
GTLV_Top, Info -> Current - 1,
TAG_DONE);
}
*Class = IDCMP_GADGETUP;
*Code = Info -> Current;
*Gadget = GadgetList[i];
}
}
GotIt = TRUE;
break;
case MX_KIND: if(Forward)
{
if(Info -> Current < Info -> Max)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTMX_Active, *Code = Info -> Current + 1,
TAG_DONE);
*Class = IDCMP_GADGETUP;
*Code = Info -> Current;
*Gadget = GadgetList[i];
}
}
else
{
if(Info -> Current > Info -> Min)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTMX_Active, *Code = Info -> Current - 1,
TAG_DONE);
*Class = IDCMP_GADGETUP;
*Code = Info -> Current;
*Gadget = GadgetList[i];
}
}
GotIt = TRUE;
break;
case PALETTE_KIND: if(Forward)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTPA_Color, (Info -> Current == Info -> Max) ? 0 : Info -> Current + 1,
TAG_DONE);
}
else
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTPA_Color, Info -> Current ? Info -> Current - 1 : Info -> Max,
TAG_DONE);
}
*Class = IDCMP_GADGETUP;
*Code = Info -> Current;
*Gadget = GadgetList[i];
GotIt = TRUE;
break;
case SCROLLER_KIND: if(Forward)
{
if(Info -> Current < Info -> Max)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTSC_Top, Info -> Current + 1,
TAG_DONE);
*Class = IDCMP_MOUSEMOVE;
*Code = Info -> Current;
*Gadget = GadgetList[i];
}
}
else
{
if(Info -> Current > Info -> Min)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTSC_Top, Info -> Current - 1,
TAG_DONE);
*Class = IDCMP_MOUSEMOVE;
*Code = Info -> Current;
*Gadget = GadgetList[i];
}
}
GotIt = TRUE;
break;
case SLIDER_KIND: if(Forward)
{
if(Info -> Current < Info -> Max)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTSL_Level, Info -> Current + 1,
TAG_DONE);
*Class = IDCMP_MOUSEMOVE;
*Code = Info -> Current;
*Gadget = GadgetList[i];
}
}
else
{
if(Info -> Current > Info -> Min)
{
GT_SetGadgetAttrs(GadgetList[i],Window,NULL,
GTSL_Level, Info -> Current - 1,
TAG_DONE);
*Class = IDCMP_MOUSEMOVE;
*Code = Info -> Current;
*Gadget = GadgetList[i];
}
}
GotIt = TRUE;
break;
default: break;
}
}
}
}
}
}
if(!GotIt)
{
for(i = 0 ; i <= Last ; i++)
{
if(!(GadgetList[i] -> Flags & GFLG_DISABLED) && (GadgetList[i] -> GadgetType & GTYP_GTYPEMASK) == GTYP_STRGADGET)
{
ActivateGadget(ActiveGadget = GadgetList[i],Window,NULL);
*Class = IDCMP_GADGETDOWN;
*Code = 0;
*Gadget = GadgetList[i];
break;
}
}
}
}
}